﻿using System;
using System.ComponentModel;
using System.Numerics;
using System.Runtime.Intrinsics.X86;
using System.Windows.Media.Animation;
using MathNet.Numerics.LinearAlgebra;

namespace GeometryMod.Models
{
    public class Tools
    {
        ///// <summary>
        ///// 四点共面判断
        ///// </summary>
        ///// <param name="A"></param>
        ///// <param name="B"></param>
        ///// <param name="C"></param>
        ///// <param name="D"></param>
        ///// <param name="epsilon"></param>
        ///// <returns></returns>
        //public static bool ArePointsCoplanar(Vector3 A, Vector3 B, Vector3 C, Vector3 D, double epsilon = 1e-7)
        //{
        //    Vector3 AB = B - A;
        //    Vector3 AC = C - A;
        //    Vector3 AD = D - A;

        //    Vector3 ABUnit = AB.ToUnitVector();
        //    Vector3 ACUnit = AC.ToUnitVector();
        //    Vector3 ADUnit = AD.ToUnitVector();

        //    Vector3 cross = Vector3.Cross(ACUnit, ADUnit);

        //    double mixedProduct = Vector3.Dot(ABUnit, cross);

        //    return Math.Abs(mixedProduct) < epsilon;
        //}

        /// <summary>
        /// 判断四点是否共面
        /// </summary>
        /// <param name="pointA">第一点(X,Y,Z)</param>
        /// <param name="pointB">第二点(X,Y,Z)</param>
        /// <param name="pointC">第三点(X,Y,Z)</param>
        /// <param name="pointD">第四点(X,Y,Z)</param>
        /// <param name="epsilon">冗余阈值</param>
        /// <returns>true 共面[共线]；false 不共面</returns>
        public static bool ArePointsCoplanar(Point3D pointA, Point3D pointB, Point3D pointC, Point3D pointD, double epsilon = 1e-7)
        {
            Vector3 AB = new Vector3((float)( pointB.X - pointA.X), (float)(pointB.Y - pointA.Y), (float)(pointB.Z - pointA.Z));
            Vector3 AC = new Vector3((float)(pointC.X - pointA.X), (float)(pointC.Y - pointA.Y), (float)(pointC.Z - pointA.Z));
            Vector3 AD = new Vector3((float)(pointD.X - pointA.X), (float)(pointD.Y - pointA.Y), (float)(pointD.Z - pointA.Z));

            Vector3 ABUnit = AB.ToUnitVector();
            Vector3 ACUnit = AC.ToUnitVector();
            Vector3 ADUnit = AD.ToUnitVector();

            Vector3 cross = Vector3.Cross(ACUnit, ADUnit);

            double mixedProduct = Vector3.Dot(ABUnit, cross);

            return Math.Abs(mixedProduct) < epsilon;
        }


        /// <summary>
        /// 三向量(四点OABC)共面判断
        /// </summary>
        /// <param name="A">OA</param>
        /// <param name="B">OB</param>
        /// <param name="C">OC</param>
        /// <param name="epsilon"></param>
        /// <returns></returns>
        public static bool ArePointsCoplanar(Vector3 A, Vector3 B, Vector3 C, double epsilon = 1e-7)
        {

            Vector3 AUnit = A.ToUnitVector();
            Vector3 CUnit = C.ToUnitVector();
            Vector3 BUnit = B.ToUnitVector();

            Vector3 cross = Vector3.Cross(AUnit, CUnit);

            double mixedProduct = Vector3.Dot(BUnit, cross);

            return Math.Abs(mixedProduct) < epsilon;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="p1">第一条线的起点</param>
        /// <param name="p2">第一条线的终点</param>
        /// <param name="p3">第二条线的起点</param>
        /// <param name="p4">第二条线的终点</param>
        /// <param name="result">交点</param>
        /// <param name="epsilon"></param>
        /// <returns>true 有交点；false 无交点</returns>
        public static bool GetIntersection(Point3D p1,Point3D p2,Point3D p3,Point3D p4, out Point3D result, double epsilon = 1e-6)
        {
            result = default;

            if (!ArePointsCoplanar(p1, p2, p3, p4))
            {
                return false;
            }

            Vector3 v1 = new Vector3((float)(p2.X - p1.X), (float)(p2.Y - p1.Y), (float)(p2.Z - p1.Z));
            Vector3 v2 = new Vector3((float)(p4.X - p3.X), (float)(p4.Y - p3.Y), (float)(p4.Z - p3.Z));

            Point3D _p1 = p1;
            Point3D _p2 = p3;
            //ly = P1+ tV1
            //ly = p2+ sV2

            //ly = _p1.x + tv1.x;
            //ly = _p2.x + sv2.x;
            // _p1.x + tv1.x = _p2.x + sv2.x
            //v1.xt-v2.xs = p1.x-p2.x
            //v1.yt-v2.ys = p1.y-p2.y

            double a1 = v1.X;
            double b1 = -v2.X;
            double c1 = _p1.X - _p2.X;

            double a2 = v1.Y;
            double b2 = -v2.Y;
            double c2 = _p1.Y - _p2.Y;


            var solution = Solve(a1, b1, c1, a2, b2, c2);
            var t = solution.x;
            var s = solution.y;

            // 验证第三个分量
            double z1 = _p1.Z + t * v1.Z;
            double z2 = _p2.Z + s * v2.Z;
            if (Math.Abs(z1 - z2) < epsilon)
            {
                result = new Point3D(_p1.X + v1.X* t, _p1.Y + v1.Y*t, _p1.Z + v1.Z*t);
                return true;
            }
            return false; 
        }

        //使用实例
        //var solution = Solve(
        //3, 2, 8,
        //2, -1, 1);
        public static (double x, double y) Solve(
      double a1, double b1, double c1,
      double a2, double b2, double c2)
        {
            // 构建主矩阵 
            var mainMatrix = Matrix<double>.Build.DenseOfArray(new[,] {
            { a1, b1 },
            { a2, b2 }
        });

            // 计算主行列式
            double D = mainMatrix.Determinant();
            if (Math.Abs(D) < 1e-12)
                throw new ArgumentException("方程组无唯一解");

            // 构建替换矩阵 
            var matrixX = Matrix<double>.Build.DenseOfArray(new[,] {
            { c1, b1 },
            { c2, b2 }
        });
            var matrixY = Matrix<double>.Build.DenseOfArray(new[,] {
            { a1, c1 },
            { a2, c2 }
        });

            // 计算行列式
            double Dx = matrixX.Determinant();
            double Dy = matrixY.Determinant();

            return (Dx / D, Dy / D);
        }
        /// <summary>
        /// 求两线[4点]的交点
        /// </summary>
        /// <param name="pt1begin"></param>
        /// <param name="pt1end"></param>
        /// <param name="pt2begin"></param>
        /// <param name="pt2end"></param>
        /// <param name="intersection"></param>
        /// <param name="epsilon"></param>
        /// <returns></returns>
        public static bool GetIntersection4(Point3D pt1begin,Point3D pt1end,Point3D pt2begin,Point3D pt2end,out Point3D intersection, double epsilon = 1e-6)
        {
            intersection = default;

            Point3D pt1 = pt1begin;
            Vector3 pt1V = new((float) (pt1end.X - pt1begin.X), (float)(pt1end.Y - pt1begin.Y), (float)(pt1end.Z - pt1begin.Z));


            Point3D pt2 = pt2begin;
            Vector3 pt2V = new((float)(pt2end.X - pt2begin.X), (float)(pt2end.Y - pt2begin.Y), (float)(pt2end.Z - pt2begin.Z));


            if (Math.Abs(pt1V.X) <= epsilon && 
                Math.Abs(pt1V.Y) <= epsilon && 
                Math.Abs(pt1V.Z) <= epsilon )
            {
                return false;
            }
            //Line 1

            /*
            ........................~M~....[Z]...................
            ........................~M~........................
            ........................~M~........................
            ........................~M~........................
            ........................~M~........................
            ........................~M~........................
            ........................~M~........................
            ........................~M~........................
            ........................~M~........................
            ........................~M~........................
            ........................~M~........................
            .......................:XMX:.......................
            ...................."REi...iER"....................
            ..................;XN}.......}NX;..................
            ...............+$K!.............!K$+...............
            ...........`IMl:...................:lMI`...........
            ..........}%F'.......................'F%}..........
            ......'F%}...............................}%F'......
            .../$&!.....................................!&$/...
            .!K$+.........................................+$K!.
            X;...............................................;X
            ..[X]..........................................[Y]..
            ...................................................
            */

            LineType line1Type = LineType.point;
            LineType line2Type = LineType.point;
   
            if (Math.Abs(pt1V.X) <= epsilon &&
                Math.Abs(pt1V.Y) <= epsilon &&
                Math.Abs(pt1V.Z) <= epsilon)
            {

                line1Type = LineType.point;
            }
            else if (Math.Abs(pt1V.X) <= epsilon &&
                Math.Abs(pt1V.Y) <= epsilon) //Line1 平行与Z轴 垂直XY平面
            {
                line1Type = LineType.parallelismZverticalXY;
            }
            else if (Math.Abs(pt1V.Z) <= epsilon &&
                Math.Abs(pt1V.Y) <= epsilon)//Line1 平行与X轴 垂直YZ平面
            {
                line1Type = LineType.parallelismXverticalYZ;
            }
            else if (Math.Abs(pt1V.Z) <= epsilon &&
                Math.Abs(pt1V.X) <= epsilon)//Line1 平行与Y轴 垂直XZ平面
            {
                line1Type = LineType.parallelismYverticalXZ;
            }
            else if(Math.Abs(pt1V.X) <= epsilon) //Line1 位于/平行 YZ 平面 垂直与X轴
            {
                line1Type = LineType.verticalX;
            }
            else if (Math.Abs(pt1V.Y) <= epsilon) //Line1 位于/平行 XZ 平面 垂直与Y轴
            {
                line1Type= LineType.verticalY;
            }
            else if (Math.Abs(pt1V.Z) <= epsilon) //Line1 位于/平行 XY 平面 垂直与Z轴
            {
                line1Type = LineType.verticalZ;
            }
            else  //Line1 斜线
            {
                line1Type = LineType.other;
            }

            if (Math.Abs(pt2V.X) <= epsilon &&
                Math.Abs(pt2V.Y) <= epsilon &&
                Math.Abs(pt2V.Z) <= epsilon)
            {

                line2Type = LineType.point;
            }
            else if (Math.Abs(pt2V.X) <= epsilon &&
                Math.Abs(pt2V.Y) <= epsilon) //Line2 平行与Z轴 垂直XY平面
            {
                line2Type = LineType.parallelismZverticalXY;

            }
            else if (Math.Abs(pt2V.Z) <= epsilon &&
                Math.Abs(pt2V.Y) <= epsilon)//Line2 平行与X轴 垂直YZ平面
            {
                line2Type = LineType.parallelismXverticalYZ;

            }
            else if (Math.Abs(pt2V.Z) <= epsilon &&
                Math.Abs(pt2V.X) <= epsilon)//Line2 平行与Y轴 垂直XZ平面
            {
                line2Type = LineType.parallelismYverticalXZ;

            }
            else if (Math.Abs(pt2V.X) <= epsilon) //Line2 位于/平行 YZ 平面 垂直与X轴
            {
                line2Type = LineType.verticalX;

            }
            else if (Math.Abs(pt2V.Y) <= epsilon) //Line2 位于/平行 XZ 平面 垂直与Y轴
            {
                line2Type = LineType.verticalY;

            }
            else if (Math.Abs(pt2V.Z) <= epsilon) //Line2 位于/平行 XY 平面  垂直与Z轴
            {
                line2Type = LineType.verticalZ;

            }
            else  //Line2 斜线
            {
                line2Type = LineType.other;

            }
            //分类计算
            if (line1Type == LineType.parallelismXverticalYZ) //平行X轴
            {
                if (line2Type == LineType.parallelismXverticalYZ) //Line2平行X轴
                {
                    return false;
                }
                else if (line2Type == LineType.parallelismYverticalXZ) //Line2平行Y轴
                {
                    //Todo: 两轴交点
                    return false;
                }
                else if (line2Type == LineType.parallelismZverticalXY) //Line2平行Z轴
                {
                    //Todo: 两轴交点
                    return false;
                }
                else if (line2Type == LineType.verticalX) //Line2垂直X轴
                {
                    //Line2 平行/位于 YZ 平面
                    //Todo: 线垂直于 YZ面
                }
                else if (line2Type == LineType.verticalY)//Line2垂直Y轴
                {
                    //Line2 平行/位于 XZ 平面

                    //Todo: 交点面平行于XZ面

                }
                else if (line2Type == LineType.verticalZ)//Line2垂直Z轴
                {
                    //Line2 平行/位于 XY 平面
                    //Todo: 交点面平行于XY面

                }
                else if (line2Type == LineType.other)//Line2其他
                {

                }
            }
            else if (line1Type == LineType.parallelismYverticalXZ) //Line1 平行Y轴
            {
                if (line2Type == LineType.parallelismXverticalYZ) //Line2平行X轴
                {
                    //Todo:交点面平行于XY面

                }
                else if (line2Type == LineType.parallelismYverticalXZ) //Line2平行Y轴
                {
                    //无交点
                }
                else if (line2Type == LineType.parallelismZverticalXY) //Line2平行Z轴
                {
                    //Todo:交点面平行于XZ面

                }
                else if (line2Type == LineType.verticalX) //Line2垂直X轴
                {
                    //Todo:交点面平行于YZ面

                }
                else if (line2Type == LineType.verticalY)//Line2垂直Y轴
                {
                    //Todo:交点面平行于XZ面

                }
                else if (line2Type == LineType.verticalZ)//Line2垂直Z轴
                {
                    //Todo:交点面平行于XY面

                }
                else if (line2Type == LineType.other)//Line2其他
                {

                }
            }
            else if (line1Type == LineType.parallelismZverticalXY) //Line1 平行Z轴
            {
                if (line2Type == LineType.parallelismXverticalYZ) //Line2平行X轴
                {
                    //Todo:交点面平行于XZ面

                }
                else if (line2Type == LineType.parallelismYverticalXZ) //Line2平行Y轴
                {
                    //Todo:交点面平行于YZ面

                }
                else if (line2Type == LineType.parallelismZverticalXY) //Line2平行Z轴
                {
                    //无交点
                }
                else if (line2Type == LineType.verticalX) //Line2垂直X轴
                {
                    //Todo:交点面平行于YZ面

                }
                else if (line2Type == LineType.verticalY)//Line2垂直Y轴
                {
                    //Todo:交点面平行于XZ面

                }
                else if (line2Type == LineType.verticalZ)//Line2垂直Z轴
                {
                    //Todo:交点面平行于XY面

                }
                else if (line2Type == LineType.other)//Line2其他
                {
                    
                }
            }
            else if (line1Type == LineType.verticalX) //Line1 垂直X轴
            {
                if (line2Type == LineType.parallelismXverticalYZ) //Line2平行X轴
                {
                    //Todo:交点面位于/平行 YZ面
                }
                else if (line2Type == LineType.parallelismYverticalXZ) //Line2平行Y轴
                {
                    //Todo:交点面位于/平行 YZ面

                }
                else if (line2Type == LineType.parallelismZverticalXY) //Line2平行Z轴
                {

                }
                else if (line2Type == LineType.verticalX) //Line2垂直X轴
                {

                }
                else if (line2Type == LineType.verticalY)//Line2垂直Y轴
                {

                }
                else if (line2Type == LineType.verticalZ)//Line2垂直Z轴
                {

                }
                else if (line2Type == LineType.other)//Line2其他
                {

                }
            }
            else if (line1Type == LineType.verticalY)//垂直Y轴
            {

            }
            else if (line1Type == LineType.verticalZ)//垂直Z轴
            {

            }
            else if (line1Type == LineType.other)//其他
            {
            
            }

                /*
                if (line1Type == LineType.point && line2Type == LineType.point) //两个点
                {
                    return false;
                }
                else if (line1Type == LineType.parallelismXverticalYZ && line2Type == LineType.parallelismXverticalYZ) //平行线 无交点
                {
                    return false;
                }
                else if (line1Type == LineType.parallelismXverticalYZ && line2Type == LineType.parallelismYverticalXZ) //XY 轴
                {

                }
                else if (line1Type == LineType.parallelismXverticalYZ && line2Type == LineType.parallelismZverticalXY) //XZ 轴
                {

                }
                else if (line1Type == LineType.parallelismYverticalXZ && line2Type == LineType.parallelismYverticalXZ) //平行线 无交点
                {
                    return false;

                }
                else if (line1Type == LineType.parallelismYverticalXZ && line2Type == LineType.parallelismXverticalYZ) //XY 轴
                {

                }
                else if (line1Type == LineType.parallelismYverticalXZ && line2Type == LineType.parallelismZverticalXY) //YZ 轴
                {

                }
                else if (line1Type == LineType.parallelismZverticalXY && line2Type == LineType.parallelismZverticalXY) //平行线 无交点
                {
                    return false;

                }
                else if (line1Type == LineType.parallelismZverticalXY && line2Type == LineType.parallelismXverticalYZ) //XZ 轴
                {

                }
                else if (line1Type == LineType.parallelismZverticalXY && line2Type == LineType.parallelismYverticalXZ) //YZ 轴
                {

                }
                */




                #region OLD DEL
                //if (Math.Abs(pt1V.X) <= epsilon &&
                //    Math.Abs(pt1V.Y) <= epsilon) //Line1 上下竖直线 Z向 线
                //{
                //    #region Line2

                //    //Line2
                //    if (Math.Abs(pt2V.X) <= epsilon &&
                //        Math.Abs(pt2V.Y) <= epsilon &&
                //        Math.Abs(pt2V.Z) <= epsilon)
                //    {
                //        return false;
                //    }
                //    if (Math.Abs(pt2V.X) <= epsilon &&
                //        Math.Abs(pt2V.Y) <= epsilon) //上下竖直线 Z向 线
                //    {
                //        if (Math.Abs(pt1.X - pt2.X) <= epsilon && Math.Abs(pt1.Y - pt2.Y) <= epsilon) //Z向 同线
                //        {
                //            return false;
                //        }
                //    }
                //    else if (Math.Abs(pt2V.Y) <= epsilon &&
                //             Math.Abs(pt2V.Z) <= epsilon) // X向 线
                //    {
                //        intersection = new Point3D(pt1begin.X, pt1begin.Y, pt2begin.Z);
                //        return true;
                //    }
                //    else if (Math.Abs(pt2V.X) <= epsilon &&
                //             Math.Abs(pt2V.Z) <= epsilon) // Y向 线
                //    {
                //        intersection = new Point3D(pt1begin.X, pt1begin.Y, pt2begin.Z);
                //        return true;

                //    }
                //    else
                //    {

                //        //L= P + tV
                //        //tV = L - P
                //        //t = (L - P)/V
                //        //t = 1 哈哈哈哈哈哈 
                //        //pt1- pt2 = v3
                //        //v3.x /v.x ?= v3.y / v.y
                //        Vector3 vP1p2b = new Vector3((float)(pt1begin.X - pt2begin.X), (float)(pt1begin.Y - pt2begin.Y), 0);
                //        if (Math.Abs(vP1p2b.X / pt2V.X - vP1p2b.Y / pt2V.Y) <= epsilon)
                //        {
                //            double t = vP1p2b.X / pt2V.X;
                //            double z = pt2begin.Z + t * pt2V.Z;
                //            intersection = new Point3D(pt1begin.X, pt1begin.Y, z);
                //            return true;
                //        }
                //        else
                //        {
                //            return false;
                //        }


                //    }
                //    #endregion

                //}
                //else if (Math.Abs(pt1V.Y) <= epsilon &&
                //         Math.Abs(pt1V.Z) <= epsilon) //Line1  X向 线
                //{
                //    #region Line2
                //    if (Math.Abs(pt2V.X) <= epsilon &&
                //        Math.Abs(pt2V.Y) <= epsilon) //Line2 上下竖直线 Z向 线
                //    {
                //        if (Math.Abs(pt1begin.Y - pt2begin.Y) <= epsilon)
                //        {
                //            intersection = new Point3D(pt2begin.X, pt1begin.Y, pt1begin.Z);
                //            return true;
                //        }
                //        return false;
                //    }
                //    else if (Math.Abs(pt2V.Y) <= epsilon &&
                //             Math.Abs(pt2V.Z) <= epsilon) //Line2  X向 线
                //    {
                //        //同线或平行线
                //        return false;
                //    }
                //    else if (Math.Abs(pt2V.X) <= epsilon &&
                //             Math.Abs(pt2V.Z) <= epsilon) //Line2  Y向 线
                //    {
                //        if (Math.Abs(pt1begin.Z - pt2begin.Z) <= epsilon)
                //        {
                //            intersection = new Point3D(pt2begin.X, pt1begin.Y, pt1begin.Z);
                //            return true;
                //        }
                //    }
                //    else // Line2 
                //    {
                //        if (Math.Abs(pt1begin.Z - pt2begin.Z) <= epsilon)
                //        {
                //            Vector3 vP1p2b = new Vector3((float)(pt1begin.X - pt2begin.X), (float)(pt1begin.Y - pt2begin.Y), 0);
                //            if (Math.Abs(vP1p2b.X / pt2V.X - vP1p2b.Y / pt2V.Y) <= epsilon)

                //            //
                //        }
                //    }

                //    #endregion

                //}
                //else if (Math.Abs(pt1V.X) <= epsilon &&
                //         Math.Abs(pt1V.Z) <= epsilon) //pt1  Y向 线
                //{
                //    #region Line2
                //    if (Math.Abs(pt2V.X) <= epsilon &&
                //        Math.Abs(pt2V.Y) <= epsilon) //Line2 上下竖直线 Z向 线
                //    {
                //        if (Math.Abs(pt1begin.Y - pt2begin.Y) <= epsilon)
                //        {
                //            intersection = new Point3D(pt2begin.X, pt1begin.Y, pt1begin.Z);
                //            return true;
                //        }
                //        return false;
                //    }
                //    else if (Math.Abs(pt2V.Y) <= epsilon &&
                //             Math.Abs(pt2V.Z) <= epsilon) //Line2  X向 线
                //    {
                //        //同线或平行线
                //        return false;
                //    }
                //    else if (Math.Abs(pt2V.X) <= epsilon &&
                //             Math.Abs(pt2V.Z) <= epsilon) //Line2  Y向 线
                //    {

                //    }
                //    else // Line2 
                //    {

                //    }

                //    #endregion

                //}
                //else
                //{
                //    #region Line2
                //    if (Math.Abs(pt2V.X) <= epsilon &&
                //        Math.Abs(pt2V.Y) <= epsilon) //Line2 上下竖直线 Z向 线
                //    {
                //        if (Math.Abs(pt1begin.Y - pt2begin.Y) <= epsilon)
                //        {
                //            intersection = new Point3D(pt2begin.X, pt1begin.Y, pt1begin.Z);
                //            return true;
                //        }
                //        return false;
                //    }
                //    else if (Math.Abs(pt2V.Y) <= epsilon &&
                //             Math.Abs(pt2V.Z) <= epsilon) //Line2  X向 线
                //    {
                //        //同线或平行线
                //        return false;
                //    }
                //    else if (Math.Abs(pt2V.X) <= epsilon &&
                //             Math.Abs(pt2V.Z) <= epsilon) //Line2  Y向 线
                //    {

                //    }
                //    else // Line2 
                //    {

                //    }

                //    #endregion

                //}


                #endregion
                return false;
        }

    }







    /// <summary>
    /// 求平面
    /// </summary>
    public static class PlaneEquation
    {
        /// <summary>
        /// 
        /// </summary>
        /// <param name="p1"></param>
        /// <param name="p2"></param>
        /// <param name="p3"></param>
        /// <returns></returns>
        /// <exception cref="ArgumentException"></exception>
        public static (double A, double B, double C, double D) Calculate(Point3D p1, Point3D p2, Point3D p3)
        {
            // 计算向量差
            double v1x = p2.X - p1.X;
            double v1y = p2.Y - p1.Y;
            double v1z = p2.Z - p1.Z;

            double v2x = p3.X - p1.X;
            double v2y = p3.Y - p1.Y;
            double v2z = p3.Z - p1.Z;

            // 叉乘计算法向量 (A,B,C)
            double A = v1y * v2z - v1z * v2y;
            double B = v1z * v2x - v1x * v2z;
            double C = v1x * v2y - v1y * v2x;

            // 判断三点是否共线（法向量模长为0）
            if (Math.Abs(A) < 1e-6 && Math.Abs(B) < 1e-6 && Math.Abs(C) < 1e-6)
                throw new ArgumentException("三点共线，无法确定唯一平面");

            // 计算D值 
            double D = -(A * p1.X + B * p1.Y + C * p1.Z);
            
            //转到单位矩阵

            var delta = Math.Sqrt(C*C + B*B + A*A) ;
            if (Math.Abs(delta) <= 1e-10)
            {
                return (0, 0, 0, 0);
            }

            A = A / delta;
            B = B / delta;
            C = C / delta;
            D = D / delta;

            return (Math.Round(A,5), Math.Round(B, 5), Math.Round(C, 5), Math.Round(D, 5));
        }
    }
}
